# /**
# * Copyright (c) 2022 Beijing Jiaotong University
# * PhotLab is licensed under [Open Source License].
# * You can use this software according to the terms and conditions of the [Open Source License].
# *
# * You may obtain a copy of [Open Source License] at: [https://open.source.license/]
# *
# * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
# * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
# * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
# *
# * See the [Open Source License] for more details.
# */
# /**
# * Author: Shihao Xie
# * Created: May. 2, 2023
# * Supported by: National Key Research and Development Program of China
# */

import time

from phot_server.rpc.file_data_type.ttypes import PhotFile, PhotFileType
from phot_server.rpc.project_data_type.ttypes import ProjectConfig, ProjectType
from phot_server.utils.phot_file import GRAPH_POSTFIX, GRID_POSTFIX


class ProjectFactory:

    def __init__(self):
        self.graph_description = "It is a {} of Optical Fiber Communication Simulation."
        self.grid_description = "It is a {} of Optical Device Simulation."

    def get_new_project_config(self, absolute_path: str, project_name: str, project_type: ProjectType):
        """
        获取一个项目配置
        :param absolute_path: 项目配置绝对路径
        :param project_name: 项目名称
        :param project_type: 项目类型
        :return: ProjectConfig 一个项目配置
        """
        if project_type == ProjectType.Optical_fiber_communication_simulation:
            return self.get_new_graph_project(absolute_path=absolute_path,
                                              project_name=project_name)
        elif project_type == ProjectType.Optical_device_simulation:
            return self.get_new_grid_project(absolute_path=absolute_path,
                                             project_name=project_name)
        else:
            return None

    def get_new_graph_project(self, absolute_path, project_name) -> ProjectConfig:
        """
        This method is to create a project in project root
        :param absolute_path: the path of project
        :param project_name: the name of project
        :return: the file in project directory
        """
        project_config = ProjectConfig(projectId=self.create_project_id(project_name, ProjectType.Optical_fiber_communication_simulation),
                                       projectName=project_name,
                                       createTime=time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()),
                                       projectDirectory=absolute_path,
                                       mainFileName=project_name,
                                       projectType=ProjectType.Optical_fiber_communication_simulation,
                                       description=self.graph_description.format("project"),
                                       files=self.__get_init_files(project_name,
                                                                   ProjectType.Optical_fiber_communication_simulation),
                                       windowConfig=None)
        return project_config

    def get_new_grid_project(self, absolute_path, project_name) -> ProjectConfig:
        project_config = ProjectConfig(projectId=self.create_project_id(project_name, ProjectType.Optical_device_simulation),
                                       projectName=project_name,
                                       createTime=time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()),
                                       projectDirectory=absolute_path,
                                       mainFileName=project_name,
                                       projectType=ProjectType.Optical_device_simulation,
                                       description=self.grid_description.format("project"),
                                       files=self.__get_init_files(project_name, ProjectType.Optical_device_simulation),
                                       windowConfig=None)
        return project_config

    def __get_init_files(self, project_name, project_type):
        files = []
        directories = ["Attachments", "Inputs", "Outputs", "Reports", "Resources"]
        if project_type == ProjectType.Optical_fiber_communication_simulation:
            main_file_name = project_name + GRAPH_POSTFIX
            main_file_type = PhotFileType.GRAPH
            project_description = self.graph_description.format("project")
            main_file_description = self.graph_description.format("graph")
        else:
            main_file_name = project_name + GRID_POSTFIX
            main_file_type = PhotFileType.GRID
            project_description = self.grid_description.format("project")
            main_file_description = self.graph_description.format("grid")

        for directory in directories:
            files.append(PhotFile(path="./" + directory,
                                  name=directory,
                                  type=PhotFileType.DIRECTORY,
                                  description=None,
                                  data=None,
                                  fileSize=None,
                                  lastAccessTime=time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()),
                                  lastModificationTime=time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()),
                                  createTime=time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())))
        config_file = PhotFile(path="./config.phtl",
                               name="config.phtl",
                               type=PhotFileType.CONFIG,
                               description=project_description,
                               data=None,
                               fileSize=None,
                               lastAccessTime=time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()),
                               lastModificationTime=time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()),
                               createTime=time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
        files.append(config_file)
        main_file = PhotFile(path="./" + main_file_name,
                             name=main_file_name,
                             type=main_file_type,
                             description=main_file_description,
                             data=None,
                             fileSize=None,
                             lastAccessTime=time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()),
                             lastModificationTime=time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()),
                             createTime=time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
        files.append(main_file)
        return files

    def create_project_id(self, project_id=None, project_type=ProjectType.Optical_fiber_communication_simulation):
        time_string = time.strftime("%Y-%m-%d_%H:%M:%S", time.localtime(time.time()))
        ptype = "Graph" if project_type == ProjectType.Optical_fiber_communication_simulation else "Grid"
        if project_id is not None:
            return ptype+"_{}_{}".format(project_id, time_string)
        else:
            return ptype+"_project_{}".format(project_id, time_string)